#import matplotlib
#matplotlib.interactive(True)
#matplotlib.use('GTKAgg')
#matplotlib.rcParams['toolbar'] = 'None'

import matplotlib.pylab as pylab
import numpy


class CrossHair(object):
    def __init__(self, axes, color='black',  horizontal=False, vertical=False):
        self._axes = axes
        self.v_cursor = None
        self.h_cursor = None
        
        if vertical is True:
            self.v_cursor = self._axes.axvline(0, color=color)
        if horizontal is True:
            self.h_cursor = self._axes.axhline(0, color=color)
        
    def redraw(self, x=None, y=None):
        if self.v_cursor is not None:
            self.v_cursor.set_xdata((x, x))
            self._axes.draw_artist(self.v_cursor)
        if self.h_cursor is not None:
            self.h_cursor.set_ydata((y, y))
            self._axes.draw_artist(self.h_cursor)

    def hide(self):
        if self.v_cursor is not None : self.v_cursor.set_visible(False)
        if self.h_cursor is not None : self.h_cursor.set_visible(False)
            
    def show(self):
        if self.v_cursor is not None : self.v_cursor.set_visible(True)
        if self.h_cursor is not None : self.h_cursor.set_visible(True)

class ImageProfile(object):
    def __init__(self, data):
        self.data = data
        self.fig = pylab.figure()
        self._draw()

    def _draw(self):
        self.fig.clear()
        self.ax1 = self.fig.add_subplot(211)
        self.ax2 = self.fig.add_subplot(212)

        # Force a draw of the image so it is cached as a background
        self.image = self.ax1.matshow(self.data)
        pylab.draw()

        self.ax1_background = self.fig.canvas.copy_from_bbox(self.ax1.bbox)
        self.ax2_background = self.fig.canvas.copy_from_bbox(self.ax2.bbox)

        self.cross_hair1 = CrossHair(self.ax1, horizontal=True, vertical=True)
        self.cross_hair2 = CrossHair(self.ax2, horizontal=False, vertical=True)

        # Plot the profile at an initial position
        self.line = self.ax2.plot(self.data[:,128], color='black')[0]
        self.ax2.set_xlim(xmax=255)
        self.ax2.set_ylim(ymax=1)
        
    def update(self, event):
        x = event.xdata
        y = event.ydata
        if x is None or y is None:
            return
        
        self.fig.canvas.restore_region(self.ax1_background)
        self.fig.canvas.restore_region(self.ax2_background)
        
        self.cross_hair1.redraw(x=x, y=y)
        self.cross_hair2.redraw(x=x)
        
        self.line.set_ydata(data[:,x])
        self.ax1.draw_artist(self.line)

        self.fig.canvas.blit(self.ax1.bbox)
        self.fig.canvas.blit(self.ax2.bbox)

    def show(self):
        self.fig.canvas.mpl_connect('motion_notify_event', self.update)
        self.fig.canvas.mpl_connect('resize_event', self._draw)
        matplotlib.interactive(False)   # Need this or there is not sys.exit
        pylab.show()


if __name__ == "__main__":
    # Cool looking data
    data = numpy.mgrid[-128:128, -128:128]
    data = numpy.sqrt(numpy.sum(data**2, axis=0))
    data = data + numpy.random.random((256, 256))*5
    data = data / data.max()

    image_profile = ImageProfile(data)
    image_profile.show()

